import sys
import layout_parser
from PyQt4 import QtGui, QtCore

class QtWindow(QtGui.QWidget):
  def __init__(self, main_window):
    super(QtWindow, self).__init__()
    self._main_window = main_window
    main_window_sizes = main_window.calculate_box_size()
    self.resize(QtCore.QSize(*main_window_sizes))
    if main_window.is_sized()[0]:
      self.setFixedWidth(main_window_sizes[0])
    if main_window.is_sized()[1]:
      self.setFixedHeight(main_window_sizes[1])
    
  def resizeEvent(self, resize_event):
    import expressions
    super(QtWindow, self).resizeEvent(resize_event)

    exp_width = self._main_window.get_box_size_expressions()[0]
    if exp_width and not exp_width.isReadonly():
      exp_width.evaluateTo(resize_event.size().width())
    exp_height = self._main_window.get_box_size_expressions()[1]
    if exp_height and not exp_height.isReadonly():
      exp_height.evaluateTo(resize_event.size().height())

    self.resize(exp_width.calculateValue(),exp_height.calculateValue())
    self.draw()
    
  def draw(self):
    self._main_window.recalculate_size()
    self._main_window.draw(self)
    exp_width, exp_height = self._main_window.calculate_box_size()
    self.resize(exp_width,exp_height)
    if self._main_window.is_sized()[0]:
      self.setFixedWidth(exp_width)
    if self._main_window.is_sized()[1]:
      self.setFixedHeight(exp_height)


class LayoutProgram(object):
  def __init__(self, code):
    self._parsed_code = layout_parser.parse(code)
    self._global_variables  = layout_parser.global_variables

  def __call__(self, d):
    qt_app = QtGui.QApplication([])
    qt_window = QtWindow(self._parsed_code["main_window"])
    for key, value in d.iteritems():
      mangled_key = layout_parser.NAME_PREFIX + key
      if mangled_key not in self._global_variables:
        raise NameError, "%s does not exist" % key
      self._global_variables[mangled_key].setInitialValue(value)
    import expressions
    expressions.redraw_function = qt_window.draw
    qt_window.show()
    qt_app.exec_()
    expressions.redraw_function = lambda: None
    return {k[len(layout_parser.NAME_PREFIX):]: v.value for k, v in self._global_variables.iteritems()}

  def when_changed(self, var_name, method):
    if layout_parser.NAME_PREFIX + var_name not in self._global_variables:
      raise NameError, "%s does not exist" % layout_parser.NAME_PREFIX + var_name
    self._global_variables[layout_parser.NAME_PREFIX + var_name].add_dependency(method)

  def bind(self, var_name, method):
    if layout_parser.NAME_PREFIX + var_name not in self._global_variables:
      raise NameError, "%s does not exist" % layout_parser.NAME_PREFIX + var_name
    self._global_variables[layout_parser.NAME_PREFIX + var_name].setInitialValue(method)

  def update(self, var_name, new_value):
    if layout_parser.NAME_PREFIX + var_name not in self._global_variables:
      raise NameError, "%s does not exist" % layout_parser.NAME_PREFIX + var_name
    self._global_variables[layout_parser.NAME_PREFIX + var_name].value = new_value


def compile(code):
  return LayoutProgram(code)


def main(args):
  import os.path
  if len(args) < 2 or not os.path.isfile(args[1]):
    print "Usage: %s <source_file_name> [argumet=value, ...]"
    sys.exit(-1)
  result = compile(file(args[1]).read())(dict(x.split("=") for x in args[2:]))
  for key_value in result.iteritems():
    print "%s=%s" % key_value


if __name__ == "__main__":
  main(sys.argv)
